/*
 * create:2016年4月16日 下午1:52:16
 * author:wangds  
 */
package com.cxkj.shop.biz;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;

import com.cxkj.shop.LevelUpCardHasBeenUsedException;
import com.cxkj.shop.LevelUpCardIsNotNeedBuyExcption;
import com.cxkj.shop.LevelUpCardIsNotNeedException;
import com.cxkj.shop.NotHaveTargetLevelUpCardException;
import com.cxkj.shop.model.card.Card;
import com.cxkj.shop.model.order.Order;
import com.cxkj.shop.model.order.OrderItem;
import com.cxkj.shop.model.shoppingcart.CommodityItem;
import com.cxkj.shop.model.user.User;
import com.cxkj.shop.proc.DefaultUpdateMybatisProc;
import com.cxkj.shop.proc.order.OrderGiftProc;
import com.cxkj.shop.utils.BusinessUtils;
import com.cxkj.shop.utils.OrderUtils;
import com.cxkj.shop.utils.UserUtils;
import com.cxkj.shop.utils.WxXmlUtils;

import net.wangds.common.context.BeanContext;
import net.wangds.comp.business.http.AbstractHttpInteractionBusiness;
import net.wangds.comp.json.JsonUtil;
import net.wangds.utilities.lang.StringUtils;

/**
 * .
 * 
 * @author wangds
 *
 */
public class PayCallBackBusiness extends AbstractHttpInteractionBusiness<String, Object> {

  private DefaultUpdateMybatisProc<Object> insLogRcdProc = null;
  private DefaultUpdateMybatisProc<Object> updTradeInfo = null;

  
  /**
   * The getter method of the property insLogRcdProc.
   * @author wangds 2016年4月17日 下午12:27:43.
   * @return the insLogRcdProc.
   */
  public DefaultUpdateMybatisProc<Object> getInsLogRcdProc() {
    return insLogRcdProc;
  }


  /**
   * The setter method of the property insLogRcdProc.
   * @param theinsLogRcdProc the insLogRcdProc to set
   * @author wangds 2016年4月17日 下午12:27:43.
   */
  public void setInsLogRcdProc(DefaultUpdateMybatisProc<Object> insLogRcdProc) {
    this.insLogRcdProc = insLogRcdProc;
  }

  

  /**
   * The getter method of the property updTradeInfo.
   * @author wangds 2016年4月17日 下午1:11:05.
   * @return the updTradeInfo.
   */
  public DefaultUpdateMybatisProc<Object> getUpdTradeInfo() {
    return updTradeInfo;
  }


  /**
   * The setter method of the property updTradeInfo.
   * @param theupdTradeInfo the updTradeInfo to set
   * @author wangds 2016年4月17日 下午1:11:05.
   */
  public void setUpdTradeInfo(DefaultUpdateMybatisProc<Object> updTradeInfo) {
    this.updTradeInfo = updTradeInfo;
  }


  /*
   * @see net.wangds.common.processor.Processor#process()
   * 
   * @author wangds 2016年4月16日 下午1:53:03.
   */
  @Override
  public void process() throws Exception {
    final String xml = this.getInput();
    try {
      String transaction_id = WxXmlUtils.cutXmlValue(xml, "transaction_id");
      final Logger logger = this.getLogger();
      new Thread(){
        public void run(){
          logger.info("weixin pay callback xml --start:" + transaction_id);
          logger.info(xml);
          logger.info("weixin pay callback xml --end:" + transaction_id);
        }
      }.start();
      

      String appid = WxXmlUtils.cutXmlValue(xml, "appid");
      String attach = WxXmlUtils.cutXmlValue(xml, "attach");
      String bank_type = WxXmlUtils.cutXmlValue(xml, "bank_type");
      String cash_fee = WxXmlUtils.cutXmlValue(xml, "cash_fee");
      String device_info = WxXmlUtils.cutXmlValue(xml, "device_info");
      String fee_type = WxXmlUtils.cutXmlValue(xml, "fee_type");
      String is_subscribe = WxXmlUtils.cutXmlValue(xml, "is_subscribe");
      String mch_id = WxXmlUtils.cutXmlValue(xml, "mch_id");
      String nonce_str = WxXmlUtils.cutXmlValue(xml, "nonce_str");
      String openid = WxXmlUtils.cutXmlValue(xml, "openid");
      String out_trade_no = WxXmlUtils.cutXmlValue(xml, "out_trade_no");
      String result_code = WxXmlUtils.cutXmlValue(xml, "result_code");
      String return_code = WxXmlUtils.cutXmlValue(xml, "return_code");
      String sign = WxXmlUtils.cutXmlValue(xml, "sign");
      String time_end = WxXmlUtils.cutXmlValue(xml, "time_end");
      String total_fee = WxXmlUtils.cutXmlValue(xml, "total_fee");
      String trade_type = WxXmlUtils.cutXmlValue(xml, "trade_type");
      //String trans_id = WxXmlUtils.cutXmlValue(xml, "transaction_id");

      String cash_fee_type = WxXmlUtils.cutXmlValue(xml, "cash_fee_type");
      String return_msg = WxXmlUtils.cutXmlValue(xml, "return_msg");
      String err_code = WxXmlUtils.cutXmlValue(xml, "err_code");
      String err_code_des = WxXmlUtils.cutXmlValue(xml, "err_code_des");
      String coupon_count = WxXmlUtils.cutXmlValue(xml, "coupon_count");
      String coupon_fee = WxXmlUtils.cutXmlValue(xml, "coupon_fee");
      String coupon_id_0 = WxXmlUtils.cutXmlValue(xml, "coupon_id_0");
      String coupon_id_1 = WxXmlUtils.cutXmlValue(xml, "coupon_id_1");
      String coupon_id_2 = WxXmlUtils.cutXmlValue(xml, "coupon_id_2");
      String coupon_id_3 = WxXmlUtils.cutXmlValue(xml, "coupon_id_3");
      String coupon_id_4 = WxXmlUtils.cutXmlValue(xml, "coupon_id_4");
      String coupon_id_5 = WxXmlUtils.cutXmlValue(xml, "coupon_id_5");
      String coupon_id_6 = WxXmlUtils.cutXmlValue(xml, "coupon_id_6");
      String coupon_id_7 = WxXmlUtils.cutXmlValue(xml, "coupon_id_7");
      String coupon_id_8 = WxXmlUtils.cutXmlValue(xml, "coupon_id_8");
      String coupon_id_9 = WxXmlUtils.cutXmlValue(xml, "coupon_id_9");
      String coupon_fee_0 = WxXmlUtils.cutXmlValue(xml, "coupon_fee_0");
      String coupon_fee_1 = WxXmlUtils.cutXmlValue(xml, "coupon_fee_1");
      String coupon_fee_2 = WxXmlUtils.cutXmlValue(xml, "coupon_fee_2");
      String coupon_fee_3 = WxXmlUtils.cutXmlValue(xml, "coupon_fee_3");
      String coupon_fee_4 = WxXmlUtils.cutXmlValue(xml, "coupon_fee_4");
      String coupon_fee_5 = WxXmlUtils.cutXmlValue(xml, "coupon_fee_5");
      String coupon_fee_6 = WxXmlUtils.cutXmlValue(xml, "coupon_fee_6");
      String coupon_fee_7 = WxXmlUtils.cutXmlValue(xml, "coupon_fee_7");
      String coupon_fee_8 = WxXmlUtils.cutXmlValue(xml, "coupon_fee_8");
      String coupon_fee_9 = WxXmlUtils.cutXmlValue(xml, "coupon_fee_9");

      final Map<String, Object> map = new HashMap<String, Object>();

      map.put("appid", appid);
      map.put("attach", attach);
      map.put("bank_type", bank_type);
      map.put("cash_fee", Integer.parseInt(cash_fee));
      map.put("device_info", device_info);
      map.put("fee_type", fee_type);
      map.put("is_subscribe", is_subscribe);
      map.put("mch_id", mch_id);
      map.put("nonce_str", nonce_str);
      map.put("openid", openid);
      map.put("out_trade_no", out_trade_no);
      map.put("result_code", result_code);
      map.put("return_code", return_code);
      map.put("sign", sign);
      map.put("time_end", time_end);
      map.put("total_fee", Integer.parseInt(total_fee));
      map.put("trade_type", trade_type);
      map.put("transaction_id", transaction_id);
      map.put("save_tm", System.currentTimeMillis());

      map.put("cash_fee_type", cash_fee_type);
      map.put("return_msg", return_msg);
      map.put("err_code", err_code);
      map.put("err_code_des", err_code_des);
      if (StringUtils.isNotBlank(coupon_count))
        map.put("coupon_count", Integer.parseInt(coupon_count));
      if (StringUtils.isNotBlank(coupon_fee))
        map.put("coupon_fee", Integer.parseInt(coupon_fee));
      map.put("coupon_id_0", coupon_id_0);
      map.put("coupon_id_1", coupon_id_1);
      map.put("coupon_id_2", coupon_id_2);
      map.put("coupon_id_3", coupon_id_3);
      map.put("coupon_id_4", coupon_id_4);
      map.put("coupon_id_5", coupon_id_5);
      map.put("coupon_id_6", coupon_id_6);
      map.put("coupon_id_7", coupon_id_7);
      map.put("coupon_id_8", coupon_id_8);
      map.put("coupon_id_9", coupon_id_9);
      if (StringUtils.isNotBlank(coupon_fee_0))
        map.put("coupon_fee_0", Integer.parseInt(coupon_fee_0));
      if (StringUtils.isNotBlank(coupon_fee_1 ))
        map.put("coupon_fee_1", Integer.parseInt(coupon_fee_1));
      if (StringUtils.isNotBlank(coupon_fee_2 ))
        map.put("coupon_fee_2", Integer.parseInt(coupon_fee_2));
      if (StringUtils.isNotBlank(coupon_fee_3 ))
        map.put("coupon_fee_3", Integer.parseInt(coupon_fee_3));
      if (StringUtils.isNotBlank(coupon_fee_4 ))
        map.put("coupon_fee_4", Integer.parseInt(coupon_fee_4));
      if (StringUtils.isNotBlank(coupon_fee_5 ))
        map.put("coupon_fee_5", Integer.parseInt(coupon_fee_5));
      if (StringUtils.isNotBlank(coupon_fee_6 ))
        map.put("coupon_fee_6", Integer.parseInt(coupon_fee_6));
      if (StringUtils.isNotBlank(coupon_fee_7 ))
        map.put("coupon_fee_7", Integer.parseInt(coupon_fee_7));
      if (StringUtils.isNotBlank(coupon_fee_8 ))
        map.put("coupon_fee_8", Integer.parseInt(coupon_fee_8));
      if (StringUtils.isNotBlank(coupon_fee_9 ))
        map.put("coupon_fee_9", Integer.parseInt(coupon_fee_9));
      
      final Map<String, Object> up_trade_map = new HashMap<String, Object>();
      up_trade_map.put("out_trade_no", out_trade_no);
      up_trade_map.put("payTm",System.currentTimeMillis());
      up_trade_map.put("wxPayId",transaction_id);
      
      if("SUCCESS".equalsIgnoreCase(result_code)){
        new Thread(){
          public void run(){
            
            Order order = OrderUtils.queryOrderByOrderId(out_trade_no);
            if(order.getPayTm()<=0){
                gift(openid, out_trade_no);//赠送买三赠一买一赠一卡
                
                buyCard(openid, order);//处理购买卡
                
            }
            
            updTradeInfo.setParameter(up_trade_map);
            updTradeInfo.process();
            int c = updTradeInfo.getResult();
            if (c != 1) {
              logger.warn("not save the payment log record for:" + xml);
            }
          }

          /**
           * .
           * @author wangds 2016年5月2日 下午8:02:58.
           * @param openid
           * @param order
           */
          protected void buyCard(String openid, Order order) {
            for(OrderItem cur:order.getItems()){
              if(cur.getType()==CommodityItem.TYPE_CARD){
                BeanContext ctx = BusinessUtils.getContext();
                Card vip = ctx.getBean("card_type_0");
                Card up1 = ctx.getBean("card_type_1");
                Card up2 = ctx.getBean("card_type_2");
                Card up3 = ctx.getBean("card_type_3");
                Card up4 = ctx.getBean("card_type_4");
                User user = UserUtils.selectUserByOpenId(openid);
                
                UserUtils.addUserBalance(user, cur.getPrice()*cur.getAmount());
                
                if(cur.getCommodityId().startsWith(vip.getId())){
                  UserUtils.setUserStatusAsVIP(user);
                }
                
                if(cur.getCommodityId().startsWith(up1.getId())){
                  try {
                    UserUtils.userBuyL0toL1Card(user);
                    UserUtils.userUseL0toL1Card(user);
                  } catch (LevelUpCardIsNotNeedException | LevelUpCardIsNotNeedBuyExcption |LevelUpCardHasBeenUsedException | NotHaveTargetLevelUpCardException e) {
                    getLogger().warn(e.getLocalizedMessage(),e);
                  }
                }
                
                if(cur.getCommodityId().startsWith(up2.getId())){
                  try {
                    UserUtils.userBuyL1toL2Card(user);
                    UserUtils.userUseL1toL2Card(user);
                  } catch (LevelUpCardIsNotNeedException | LevelUpCardIsNotNeedBuyExcption |LevelUpCardHasBeenUsedException | NotHaveTargetLevelUpCardException e) {
                    getLogger().warn(e.getLocalizedMessage(),e);
                  }
                }
                
                
                if(cur.getCommodityId().startsWith(up3.getId())){
                  try {
                    UserUtils.userBuyL2toL3Card(user);
                    UserUtils.userUseL2toL3Card(user);
                  } catch (LevelUpCardIsNotNeedException | LevelUpCardIsNotNeedBuyExcption |LevelUpCardHasBeenUsedException | NotHaveTargetLevelUpCardException e) {
                    getLogger().warn(e.getLocalizedMessage(),e);
                  }
                }
                
                
                if(cur.getCommodityId().startsWith(up4.getId())){
                  try {
                    UserUtils.userBuyL3toL4Card(user);
                    UserUtils.userUseL3toL4Card(user);
                  } catch (LevelUpCardIsNotNeedException | LevelUpCardIsNotNeedBuyExcption |LevelUpCardHasBeenUsedException | NotHaveTargetLevelUpCardException e) {
                    getLogger().warn(e.getLocalizedMessage(),e);
                  }
                }
              }
            }
          }

          /**
           * .
           * @author wangds 2016年5月2日 下午7:55:33.
           * @param openid
           * @param out_trade_no
           */
          protected void gift(String openid, String out_trade_no) {
            final Map<String, Object> map = new HashMap<String, Object>();
            map.put(OrderGiftProc.KEY_OPEN_ID,openid);
            map.put(OrderGiftProc.KEY_TRADE_NO, out_trade_no);
            
            OrderGiftProc proc = new OrderGiftProc();
            proc.setIntput(map);
            try {
              proc.process();
            } catch (Exception e) {
              getLogger().error(e.getLocalizedMessage(),e);
            }finally{
              if(proc.getResult()){
                getLogger().warn(StringUtils.join(OrderGiftProc.class.getName()," execute fail, parameter:",JsonUtil.toJson(map)));
              }
            }
          }
        }.start();
        
        
      }

      new Thread(){
        public void run(){
          insLogRcdProc.setParameter(map);
          insLogRcdProc.process();
          int c = insLogRcdProc.getResult();
          logger.debug("ins logRec proc res:" + c);
          if (c != 1) {
            logger.warn("not save the payment log record for:" + xml);
          }
        }
      }.start();
      

    } catch (Exception e) {
      this.getLogger().error(e.getLocalizedMessage(), e);
      e.printStackTrace();
    }
  }

}
